import { ColumnType } from 'ant-design-vue/lib/table'
import { Reactive, reactive, ref, Ref } from 'vue'
import { ISearchWhere, Paging } from './paging'
import router from '@/router'
import { Utilts } from '../utilts'
import { API } from '@/api/api'
import { TableColumnType } from 'ant-design-vue'

/**
 * AdvantageService
 */
export abstract class UseTableService<IDataList, IWhere> {
  public name = '';
  public pageIndex = 1;
  public pageSize = 10;
  public keyword = ref('');
  public getPatationList: (payload: any, filters?: {}, sorter?: {}) => void;
  public paging: Reactive<Paging<IDataList[], IWhere>>;
  public addFiled: string[] = []
  public sorter: any = {}

  private columnList: ColumnType[] = []
  private payload: any = {}
  private filters: any = {}


  /**
   * 构造
   * @date 2022-03-10
   * @param {any} name:string
   * @param {any} pageIndex=1
   * @param {any} pageSize=10
   */
  constructor(name: string = '', pageIndex = 1, pageSize = 10) {
    this.name = name
    this.pageIndex = pageIndex
    this.pageSize = pageSize
  }
  /**
   * 查找分页数据
   * @param {IWhere} where
   */
  public getList(): Promise<UsePaging<IDataList>> {
    return new Promise(async (resolve, reject) => {
      const where = this.getPageWhere();
      const pageInput = {
        page: this.pageIndex,
        limit: this.pageSize,
        query: where,
        sorter: this.sorter,
      }
      // 获取字段
      const fields = this.getFields()
      API.Query?.[`find${this.name}Page`](pageInput, fields)
        .then(resData => {
          if (resData) {
            const resultData = {
              total: resData.total,
              pageSize: this.pageSize,
              pageIndex: this.pageIndex,
              list: resData.items,
            }
            resolve(resultData)
          }
        });
    })
  }

  /**
   * 表格列
   */
  abstract columns(refData?: Ref<any>): ColumnType[]

  /**
   * 查询条件
   * @date 2022-03-10
   * @return {any}
   */
  abstract getPageWhere(): IWhere

  /**
   * 导出数据
   * @param {其它数据} refData
   * @return {any}
   */
  public usePagin(refData?: Ref<any>) {
    // 初始化分页器
    this.paging = reactive(new Paging<IDataList[], IWhere>(this.pageIndex, this.pageSize))
    // 初始化表格列
    this.paging.columns = this.columns(refData)
    // 获取列表数据方法
    const getList = () => this.paging.requestPaging(this.getList.bind(this))
    // 获取列表数据
    this.getPatationList = (payload: any, filters: any = {}, sorter: any = {}) => {
      this.payload = payload ?? {}
      this.filters = filters ?? {}
      this.sorter = sorter ?? {}

      this.paging.pageIndex = payload?.current ?? this.pageIndex
      this.pageIndex = this.paging.pageIndex

      this.paging.pageSize = payload?.pageSize ?? this.pageSize
      this.pageSize = this.paging.pageSize

      if (filters) {
        Object.keys(filters).forEach((key) => {
          if (!filters[key]) delete filters[key]
        })
      }

      this.paging.where = this.filters;
      this.paging.sorter = this.sorter;

      getList()
    }
    const onSearch = (keyword: string) => {
      this.filters.keyword = keyword
      this.getPatationList(this.payload, this.filters, this.sorter)
    }
    // 多选改变事件
    const onSelectChange = (selectedRowKeys: number[]) => {
      this.paging.selectedRowKeys = selectedRowKeys
    }

    getList();

    return {
      onSearch,
      onSelectChange,
      paging: this.paging,
      getPatationList: this.getPatationList,
    }
  }

  /**
   * 描述
   * @date 2022-03-15
   * @param {any} title:string
   * @param {any} key:string
   * @param {any} sorter:false
   * @return {any}
   */
  public getColumns(title: string, key: DotNotation<IDataList> | 'action' | 'rowIndex', sorter = false) {
    let column: TableColumnType = null;
    const myKey = key.toString()
    if (key === 'rowIndex') {
      column = {
        title, dataIndex: myKey, key: myKey, sorter, width: 60,
        customRender: (opt: any) =>
          `${(this.pageIndex - 1) * this.pageSize + opt.index + 1}`,
      }
    } else column = { title, dataIndex: myKey, key: myKey, sorter }
    if (this.columnList.findIndex(p => p.key === myKey) === -1) {
      this.columnList.push(column)
    }
    return column;
  }

  /**
   * 获取当前选中的数据
   * @date 2022-03-10
   * @param {any} id:number
   * @return {any}
   */
  public getInfo(id: number) {
    const info = this.paging.dataSource?.find((p: any) => {
      return p.id === id
    })
    return info
  }

  /**
   * 跳转url
   * @date 2022-03-21
   * @param {any} name:string
   * @param {any} params
   */
  public goUrl(name: string, params: any) {
    router.push({ name, params })
  }

  /**
   * 删除表格数据
   * @date 2022-03-10
   * @param {any} id:number
   */
  public delInfo(id: number) {
    API.Mutation?.[`softDelete${this.name}`](id, ['_id']).then(response => {
      if (response._id) {
        this.paging.dataSource = this.paging.dataSource?.filter((p: any) => p._id !== id)
        Utilts.ins().message('删除成功')
      }
    })
  }

  /**
   * 重置表格
   * @date 2022-03-10
   */
  public resultList() {
    this.paging.pageIndex = 1
    this.paging.dataSource = []
    const where = this.paging.where;
    this.getPatationList({ where, current: 1 }, {}, {})
  }

  /**
   * 删除提示
   * @date 2022-03-21
   * @param {any} okCallBack:any
   * @param {any} cancelCallBack:any
   */
  public delConfirm(okCallBack: () => void, cancelCallBack?: () => void) {
    Utilts.ins().confirm({ cancelCallBack, okCallBack })
  }

  private getFields(): string[] {
    const whiteList = ["rowIndex", "action"];
    const fields = this.columnList.filter(p => !whiteList.includes(p.key.toString()))
      .map(p => `items.${p.key.toString()}`)
    fields.push('items._id')
    fields.push('page')
    fields.push('limit')
    fields.push('total')
    this.addFiled.forEach(p => fields.push(p))
    return fields
  }
}
